iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0

還沒有玩過的朋友,來想再玩一次的朋友,更新版本傳送門:
https://wowdacom.github.io/TimelineQuest-ithelp-sample/

完成事項

  • [V] Bug 修正
  • [V] 優化重構
  • [V] 新增功能 關閉頁面後分數紀錄

Bug 修正

修正目前答題題目標記的藍色框
以下是相關的程式碼片段:

<ul class="flex items-center">
    <li
        v-for="(isCorrect, index) in gameStatus.stepCorrect"
        :key="index"
        class="w-6 h-2.5 mr-[2px] border-2 rounded-full"
        :class="
            gameStatus.currentStep === index + 1
                ? 'border-[#5d72c9]'
                : isCorrect === null
                ? 'bg-[#e3e0d5] border-[#e3e0d5]'
                : isCorrect
                ? 'bg-[#5cb887] border-[#5cb887]'
                : 'bg-[#d25353] border-[#d25353]'
        "
    />
</ul>

https://ithelp.ithome.com.tw/upload/images/20231012/20107703idgPdEeHkG.png

資料優化

1. 簡化與移除不必要的 switch 判斷式

之前根據 ChatGPT 的建議將卡片位置更新的邏輯獨立出一個 function updateTimelineEventsPosition,後來發現有過度優化的傾向。後來我 switch case簡化為一行的 if 判斷式,並移除 function updateTimelineEventsPosition 使整個函式閱讀起來更為直覺。

https://ithelp.ithome.com.tw/upload/images/20231012/20107703tilsKXbzwB.png

  1. 移除不必要的 handleLineShare click 事件

新增功能

新增遊戲紀錄功能

  1. 在離開網頁時候,紀錄狀態資料。
    我新增了一個功能,當用戶離開網頁時,會自動保存遊戲的當前狀態。
const saveGameStatus = () => {
    if (gameStatus.currentStep > 1 && gameStatus.currentStep < 9) {
        localStorage.setItem(
            'gameStatus',
            JSON.stringify({
                ...gameStatus,
                clues: clues.value,
                timelineEvents: timelineEvents.value,
                selectedYear: selectedYear.value,
            }),
        );
    } else {
        localStorage.removeItem('gameStatus');
    }

    window.removeEventListener('beforeunload', saveGameStatus);
    return null;
};

window.addEventListener('beforeunload', saveGameStatus);

在進入遊戲時,藉由抓取 localStorage 資料判斷是否已經玩過遊戲

const gameInit = () => {
    const savedGameStatus = loadGameStatus();
    if (savedGameStatus) {
        isPlayed.value = true;
    } else {
        isPlayed.value = false;
    }
};
  1. 新增「重新開始」和「繼續遊戲」按鈕
    最後有三種不同的進入遊戲按鈕,包括「開始(新)遊戲」、「繼續遊戲」和「重新開始」。
<div v-if="isPlayed">
    <div class="text-center font-extrabold m-1 text-[#5d72c9]">
        <span class="">{{ selectedYear }} </span>那年出生的你,選擇要…
    </div>
    <div class="flex">
        <button data-test="game-start-btn" class="rounded-full border w-[130px] h-[40px] bg-[#5d72c9] text-white flex justify-center items-center" @click="handleGameStart(true)">
            重新開始 <i-solar-restart-square-bold class="ml-1 inline-block" />
        </button>
        <button data-test="game-start-btn" class="rounded-full border w-[130px] h-[40px] bg-[#5d72c9] text-white flex justify-center items-center" @click="handleGameKeep">
            繼續遊戲 <i-maki-arrow class="ml-1 inline-block" />
        </button>
    </div>
</div>
<div v-else>
    <div class="mb-2 flex">
        <h1>選擇出生年份</h1>
        <select v-model="selectedYear" class="text-[#5d72c9] font-extrabold">
            <option v-for="year in yearOptions" :key="year" :value="year">
                {{ year }}
            </option>
        </select>
    </div>
    <button data-test="game-start-btn" class="rounded-full border w-[150px] h-[40px] bg-[#5d72c9] text-white" @click="handleGameStart(false)">
        開始遊戲 <i-maki-arrow class="inline-block" />
    </button>
</div>
//開始(新)遊戲
const handleGameStart = (isRestart) => {
    if (!isRestart) {
        isShowTip.value = true;
    }
    isGameStart.value = true;
    clues.value = [...cluesData];
    timelineEvents.value = [];
    timelineEvents.value.push({
        year: `${selectedYear.value}`,
        event: '一個孩子誕生囉!',
        description: '慶祝生命的多彩多姿,每一刻都值得紀念和珍惜。',
        image: 'https://i.imgur.com/xTWeFPu.jpg',
        point: 0,
        step: 0,
    });
    handleUpdateTimelinePosition(gameStatus.currentStep);
}; 

//繼續遊戲
const handleGameKeep = () => {
    const savedGameStatus = loadGameStatus();
    isGameStart.value = true;
    isShowTip.value = false;
    Object.assign(gameStatus, savedGameStatus);
    clues.value = savedGameStatus.clues;
    timelineEvents.value = savedGameStatus.timelineEvents;
    selectedYear.value = savedGameStatus.selectedYear;
    handleUpdateTimelinePosition(gameStatus.currentStep);
};

//重新開始


const handleGameReset = () => {
    isGameEnd.value = false;
    isGameStart.value = false;
    Object.assign(gameStatus, JSON.parse(JSON.stringify(initialGameState)));
    handleUpdateTimelinePosition(gameStatus.currentStep);
    isPlayed.value = false;
    localStorage.removeItem('gameStatus');
};

上一篇
優化 (重構)
下一篇
展望與延伸功能 輸入姓名出生年 與 GAS 紀錄出生年
系列文
打造紐時風格的時間線小遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言